/**
 * 如何限制Promise“并发”的数量
 */
class LimitPromise {
    constructor(max) {
        // 异步任务“并发”上限
        this._max = max;

        // 当前正在执行的任务数量
        this._count = 0;

        // 任务队列
        this._task_queue = [];
    }

    /**
     * 创建异步任务
     * @param {*} caller 
     * @param {*} args 
     * @param {*} resolve 
     * @param {*} reject 
     */
    _createTask(caller, args, resolve, reject) {
        return () => {
            caller(args).then(resolve).catch(reject).finally(() => {
                this._count--;
                if (this._task_queue.length) {
                    const task = this._task_queue.shift();
                    task();
                }
            });
            this._count++;
        };
    }

    /**
     * 调用器
     * @param {*} caller 异步任务函数，async声明函数或者promise
     * @param  {...any} args 异步任务函数参数
     */
    call(caller, ...args) {
        return new Promise((resolve, reject) => {
            const task = this._createTask(caller, args, resolve, reject);
            if (this._count >= this._max) {
                this._task_queue.push(task);
            }
            else {
                task();
            }
        });
    }
}

function func1() {
    console.log('func1');
}

function func2() {
    console.log('func2');
}

function func3() {
    console.log('func3');
}

function func4() {
    console.log('func4');
}

const promise = new LimitPromise(3);
promise.call(func1);
promise.call(func2);
promise.call(func3);
promise.call(func4);